package com.fmdj.bff.driver.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.fmdj.bff.driver.controller.form.*;
import com.fmdj.bff.driver.feign.*;
import com.fmdj.bff.driver.service.OrderService;
import com.fmdj.common.exception.GlobalException;
import com.fmdj.common.util.CommonResult;
import com.fmdj.common.util.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OdrServiceApi odrServiceApi;

    @Autowired
    private CstServiceApi cstServiceApi;

    @Autowired
    private NebulaServiceApi nebulaServiceApi;

    @Autowired
    private FeeServiceApi feeServiceApi;
    
    @Autowired
    private SnmServiceApi snmServiceApi;
    
    
    @Transactional
    @LcnTransaction
    @Override
    public String acceptNewOrder(AcceptNewOrderForm form) {
        CommonResult commonResult = odrServiceApi.acceptNewOrder(form);
        String result = (String) commonResult.get(CommonResult.RETURN_RESULT);
        return result;
    }

    @Override
    public HashMap searchDriverExecuteOrder(SearchDriverExecuteOrderForm form) {
        //查询订单信息 完成后再将查出的customerId传给cstServiceApi查询出顾客信息
        CommonResult r = odrServiceApi.searchDriverExecuteOrder(form);
        HashMap orderMap = (HashMap) r.get(CommonResult.RETURN_RESULT);
        Long customerId = MapUtil.getLong(orderMap, "customerId");

        SearchCustomerInfoInOrderForm form2 = new SearchCustomerInfoInOrderForm();
        form2.setCustomerId(customerId);
        r = cstServiceApi.searchCustomerInfoInOrder(form2); /*这里的r会将上面的r覆盖 上面的r已经没用了 所以可以重复利用 减少资源消耗*/
        HashMap cstMap = (HashMap) r.get(CommonResult.RETURN_RESULT);

        //整合结果集 将订单信息和顾客信息放入结果集中
        HashMap result = new HashMap<>();
        result.putAll(orderMap);  //putAll 将cstMap中的内容放入result中
        result.putAll(cstMap);

        return result;
    }

    @Override
    public HashMap searchDriverCurrentOrder(SearchDriverCurrentOrderForm form) {
        CommonResult r = odrServiceApi.searchDriverCurrentOrder(form);
        HashMap odrMap = (HashMap) r.get(CommonResult.RETURN_RESULT);

        //先判断是否有订单 如何有 则查询顾客信息 最后把订单信息和顾客信息整合到一起
        if (odrMap!=null) {

            HashMap hashMap = new HashMap();

            Long customerId = MapUtil.getLong(odrMap, "customerId");
            SearchCustomerInfoInOrderForm customerForm = new SearchCustomerInfoInOrderForm();
            customerForm.setCustomerId(customerId);
            r = cstServiceApi.searchCustomerInfoInOrder(customerForm);
            HashMap cstMap = (HashMap) r.get(CommonResult.RETURN_RESULT);

            hashMap.putAll(odrMap);
            hashMap.putAll(cstMap);

            return hashMap;
        }
        return null;
    }

    @Override
    public HashMap searchOrderForMoveById(SearchOrderForMoveByIdForm form) {
        CommonResult r = odrServiceApi.searchOrderForMoveById(form);
        HashMap hashMap = (HashMap) r.get(CommonResult.RETURN_RESULT);
        return hashMap;
    }

    @Override
    @Transactional
    @LcnTransaction
    public int arriveStartPlace(ArriveStartPlaceForm form) {
        CommonResult r = odrServiceApi.arriveStartPlace(form);
        Integer rows = MapUtil.getInt(r, CommonResult.RETURN_ROW);
        if (rows!=1) {
            throw new GlobalException("更新订单状态失败");
        }
        return rows;
    }

    @Override
    public int startDriving(StartDrivingForm form) { //在开始代驾时插入订单监控摘要记录
        CommonResult r = odrServiceApi.startDriving(form);
        Integer rows = MapUtil.getInt(r, CommonResult.RETURN_ROW);
        if (rows==1) {
            //插入一条订单监控摘要记录
            InsertOrderMonitoringForm monitoringForm = new InsertOrderMonitoringForm();
            Long orderId = form.getOrderId();
            monitoringForm.setOrderId(orderId);
            nebulaServiceApi.insertOrderMonitoring(monitoringForm);
        }
        return rows;
    }

    @Override
    @Transactional
    @LcnTransaction
    public int updateOrderStatus(UpdateOrderStatusForm form) {
        CommonResult r = odrServiceApi.updateOrderStatus(form);
        Integer rows = MapUtil.getInt(r, CommonResult.RETURN_ROW);
        if (rows!=1) {
            throw new GlobalException("更新订单状态失败");
        }

        if (form.getStatus() == 6) {
            //如果状态为6 说明司机点击发送订单
            ///异步发送消息 该消息会在一个独立的线程进行 速度更快
            SendPrivateMessageForm entity = new SendPrivateMessageForm();
            entity.setReceiverId(form.getCustomerId());
            entity.setReceiverIdentity("customer_bill");
            entity.setTtl(3*24*60*60*1000); //3天=259200000毫秒 里面的单位是毫秒
            entity.setSenderIdentity("system");
            entity.setSenderName("飞马代驾");
            entity.setMsg("您有代驾订单待支付");
            entity.setSenderId(0L); //0 代表系统发送的消息
            snmServiceApi.sendPrivateMessageAsync(entity);
        }
        return rows;
    }

    @Override
    @Transactional
    @LcnTransaction
    public int updateOrderBill(UpdateBillFeeForm form) {
        //判断司机是否关联该订单
        ValidDriverOwnOrderForm form_1 = new ValidDriverOwnOrderForm();
        form_1.setOrderId(form.getOrderId());
        form_1.setDriverId(form.getDriverId());
        CommonResult r = odrServiceApi.validDriverOwnOrder(form_1);
        Boolean bool = (Boolean) r.get(CommonResult.RETURN_RESULT);
        if (!bool) {
            throw new GlobalException("该司机没有关联相关订单");
        }

        //计算代驾里程
        CalculateOrderMileageForm form_2 = new CalculateOrderMileageForm();
        form_2.setOrderId(form.getOrderId());
        r = nebulaServiceApi.calculateOrderMileage(form_2);
        String mileage = (String) r.get(CommonResult.RETURN_RESULT);
        //保留一位小数并向上取整 例如:2.132 -> 2.2
        mileage = NumberUtil.div(mileage, "1", 1,RoundingMode.CEILING).toString(); //除1 保1 向上取整
        form.setRealMileage(mileage);

        //查询订单相关信息
        SearchSettlementNeedDataForm form_3 = new SearchSettlementNeedDataForm();
        form_3.setOrderId(form.getOrderId());
        r = odrServiceApi.searchSettlementNeedData(form_3);
        HashMap hashMap = (HashMap) r.get(CommonResult.RETURN_RESULT);
        String favourFee = MapUtil.getStr(hashMap, "favourFee");

        //计算代驾费用
        CalculateOrderChargeForm form_4 = new CalculateOrderChargeForm();
        r = feeServiceApi.calculateOrderCharge(form_4);
        HashMap driveFee = (HashMap) r.get(CommonResult.RETURN_RESULT);
        String amount = MapUtil.getStr(driveFee, "amount");
        String mileageFee = MapUtil.getStr(driveFee, "mileageFee");
        String waitingFee = MapUtil.getStr(driveFee, "waitingFee");
        String returnMileage = MapUtil.getStr(driveFee, "returnMileage");
        String returnFee = MapUtil.getStr(driveFee, "returnFee");


        form.setMileageFee(mileageFee);
        form.setWaitingFee(waitingFee);
        form.setReturnMileage(returnMileage);
        form.setReturnFee(returnFee);

        //获取系统好处费
        CalculateIncentiveFeeForm form_5 = new CalculateIncentiveFeeForm();
        r = feeServiceApi.calculateIncentiveFee(form_5);
        String incentiveFee = (String) r.get(CommonResult.RETURN_RESULT);
        form.setIncentiveFee(incentiveFee);

        //计算总费用
        BigDecimal total = NumberUtil.add(amount, form.getParkingFee(), form.getTollFee(), form.getOtherFee(), favourFee);
        form.setTotal(total.toString());

        //计算分账费用
        CalculateProfitsharingForm form_6 = new CalculateProfitsharingForm();
        r = feeServiceApi.calculateProfitsharing(form_6);
        HashMap profitSharing = (HashMap) r.get(CommonResult.RETURN_RESULT);
        Long ruleId = MapUtil.getLong(profitSharing, "ruleId");
        String paymentRate = MapUtil.getStr(profitSharing, "paymentRate");
        String paymentFee = MapUtil.getStr(profitSharing, "paymentFee");
        String systemIncome = MapUtil.getStr(profitSharing, "systemIncome");
        String taxRate = MapUtil.getStr(profitSharing, "taxRate");
        String taxFee = MapUtil.getStr(profitSharing, "taxFee");
        String driverIncome = MapUtil.getStr(profitSharing, "driverIncome");

        form.setRuleId(ruleId);
        form.setPaymentRate(paymentRate);
        form.setPaymentFee(paymentFee);
        form.setSystemIncome(systemIncome);
        form.setTaxRate(taxRate);
        form.setTaxFee(taxFee);
        form.setDriverIncome(driverIncome);

        r = odrServiceApi.updateBillFee(form);
        int rows = (int) r.get(CommonResult.RETURN_ROW);
        if (rows!=1) {
            throw new GlobalException("更新订单账单费用失败");
        }

        return rows;
    }

    @Override
    public HashMap searchReviewDriverOrderBill(SearchReviewDriverOrderBillForm form) {
        CommonResult commonResult = odrServiceApi.searchReviewDriverOrderBill(form);
        HashMap hashMap = (HashMap) commonResult.get(CommonResult.RETURN_RESULT);
        return hashMap;
    }

    @Override
    public int searchOrderStatus(SearchOrderStatusForm form) {
        CommonResult r = odrServiceApi.searchOrderStatus(form);
        Integer status = MapUtil.getInt(r, CommonResult.RETURN_RESULT);
        return status;
    }

    @Override
    public String updateOrderAboutPayment(long driverId, UpdateOrderAboutPaymentForm form) {
        //判断司机是否关联该订单
        ValidDriverOwnOrderForm vf = new ValidDriverOwnOrderForm();
        vf.setDriverId(driverId);
        CommonResult r = odrServiceApi.validDriverOwnOrder(vf);
        Boolean bool = MapUtil.getBool(r, CommonResult.RETURN_RESULT);
        if (!bool){
            throw new GlobalException("该司机未关联该订单");
        }

        //执行 异步通知以及主动查询都没有进行的业务逻辑
        r = odrServiceApi.updateOrderAboutPayment(form);
        String result = MapUtil.getStr(r, CommonResult.RETURN_RESULT);

        return result;
    }

    @Override
    public PageUtils searchDriverOrderByPage(SearchDriverOrderByPageForm form) {
        CommonResult r = odrServiceApi.searchDriverOrderByPage(form);
        //转换成PageUtils 不能直接强转成pageUtils因为CommonResult.RETURN_RESULT中是一个map
        HashMap hashMap = (HashMap) r.get(CommonResult.RETURN_RESULT);
        PageUtils pageUtils = BeanUtil.toBean(hashMap, PageUtils.class);
        return pageUtils;
    }

    @Override
    public HashMap searchOrderById(SearchOrderByIdForm form) {
        //查询订单相关信息
        SearchOrderByIdForm form_1 = new SearchOrderByIdForm();
        form_1.setDriverId(form.getDriverId());
        form_1.setOrderId(form.getOrderId());
        CommonResult r = odrServiceApi.searchOrderById(form_1);
        HashMap orderMap = (HashMap) r.get(CommonResult.RETURN_RESULT);

        //查询代驾顾客相关信息
        SearchCustomerInfoInOrderForm form_2 = new SearchCustomerInfoInOrderForm();
        Long customerId = MapUtil.getLong(orderMap, "customerId");
        form_2.setCustomerId(customerId);
        r = cstServiceApi.searchCustomerInfoInOrder(form_2);
        HashMap cstMap = (HashMap) r.get(CommonResult.RETURN_RESULT);

        //查询评价相关信息
        Integer status = MapUtil.getInt(orderMap, "status");
        HashMap cmtMap = new HashMap();
        if (status>=7) {
            SearchCommentByOrderIdForm form_3 = new SearchCommentByOrderIdForm();
            form_3.setOrderId(form.getOrderId());
            form_3.setDriverId(form.getDriverId());
            r = odrServiceApi.searchCommentByOrderId(form_3);
            if (r.containsKey(CommonResult.RETURN_RESULT)) {
                //存在评价信息则取出
                cmtMap = (HashMap) r.get(CommonResult.RETURN_RESULT);
            }else{
                //不存在则默认为五星好评
                cmtMap.put("rate", "5");
            }
        }

        //把所有map信息都放在一个map中返回
        HashMap map = new HashMap<>();
        map.putAll(orderMap);
        map.putAll(cstMap);
        map.put("comment", cmtMap);

        return map;
    }


}
